using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using System.IO;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Administration;

namespace Microsoft.MCSUK.SPSiteDirectory2010.Features.AddSiteListingContentType
{
    /// <summary>
    /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
    /// </summary>
    /// <remarks>
    /// The GUID attached to this class may be used during packaging and should not be modified.
    /// </remarks>

    [Guid("e0d72961-e7dc-481e-9d55-788dbc82fb0d")]
    public class AddSiteListingContentTypeEventReceiver : SPFeatureReceiver
    {
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            GlobalMethods globalMethods = new GlobalMethods();
            GlobalSolutionSettings globalSolutionSettings = new GlobalSolutionSettings().GetOrCreateGlobalSolutionSettings(SPFarm.Local);
            try
            {
                if (globalMethods.DoesSiteExist(globalSolutionSettings.SiteDirectoryURL))
                {
                    using (SPSite siteDirectorySite = new SPSite(globalSolutionSettings.SiteDirectorySiteGuid))
                    {
                        using (SPWeb siteDirectoryWeb = siteDirectorySite.OpenWeb(globalSolutionSettings.SiteDirectoryWebGuid))
                        {
                            SPList siteListingsList = siteDirectoryWeb.Lists["Site Listings"];

                            //get site listing content type
                            SPContentTypeId ctParentID = new SPContentTypeId("0x010029DEB30151FB463B86F0E019EB8BFE70");
                            SPContentType ct = GetCTIfExists(siteListingsList, ctParentID);
                            if (ct == null)
                            {
                                SPContentType siteListingCT = siteDirectoryWeb.AvailableContentTypes[ctParentID];

                                //add to list
                                SPContentType addedContentType = siteListingsList.ContentTypes.Add(siteListingCT);

                                //re-order
                                SPFolder folder = siteListingsList.RootFolder;
                                SPContentType[] ctOrder = new SPContentType[1];
                                ctOrder[0] = siteListingsList.ContentTypes[addedContentType.Id];
                                folder.UniqueContentTypeOrder = ctOrder;
                                folder.Update();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                globalMethods.WriteULSEntry(ex, TraceSeverity.Unexpected, null);
            }
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            GlobalMethods globalMethods = new GlobalMethods();
            GlobalSolutionSettings globalSolutionSettings = new GlobalSolutionSettings().GetOrCreateGlobalSolutionSettings(SPFarm.Local);
            try
            {
                if (globalMethods.DoesSiteExist(globalSolutionSettings.SiteDirectoryURL))
                {
                    using (SPSite siteDirectorySite = new SPSite(globalSolutionSettings.SiteDirectorySiteGuid))
                    {
                        using (SPWeb siteDirectoryWeb = siteDirectorySite.OpenWeb(globalSolutionSettings.SiteDirectoryWebGuid))
                        {
                            SPList siteListingsList = siteDirectoryWeb.Lists["Site Listings"];
                            SPContentTypeId ctParentID = new SPContentTypeId("0x010029DEB30151FB463B86F0E019EB8BFE70");
                            SPContentType ct = GetCTIfExists(siteListingsList, ctParentID);
                            if (ct != null)
                            {
                                siteListingsList.ContentTypes.Delete(ct.Id);
                                siteListingsList.Update();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                globalMethods.WriteULSEntry(ex, TraceSeverity.Unexpected, null);
            }
        }

        private SPContentType GetCTIfExists(SPList list, SPContentTypeId ctID)
        {
            SPContentType ct = null;
            foreach (SPContentType ctInList in list.ContentTypes)
            {
                if (ctInList.Id.IsChildOf(ctID)) //when cts are added to a list they are actually a copy of the site ct. Therefore we need to check whether the list CT is a child of the site CT, not a direct match if CT ID
                {
                    ct = ctInList;
                    break;
                }
            }
            return ct;
        }
    }
}
